package backend.opt;

import backend.Instruction.RISCVmove;
import backend.component.RISCVblock;
import backend.component.RISCVfunction;
import backend.Instruction.RISCVinst;
import backend.component.RISCVmodule;
import backend.Register.RISCVoperand;
import backend.Register.virtualFReg;
import backend.Register.virtualReg;

import java.util.HashSet;
import java.util.Iterator;

public class removeUselessReg {
    private final RISCVmodule asmModule;
    private final HashSet<RISCVoperand> ifUsed = new HashSet<>();

    public removeUselessReg(RISCVmodule asmModule) {
        this.asmModule = asmModule;
    }

    public void run() {
        removeNoUseReg();
    }

    private void removeNoUseReg() {
        boolean changed = true;
        while(changed) {
            ifUsed.clear();
            changed = false;
            for (RISCVfunction objFunction : asmModule.getFunctions()) {
                // 移除目标和源寄存器相同的 RISCVmove 指令
                for (RISCVblock asmBlock : objFunction.getBlocks()) {
                    asmBlock.getInstructionlist().removeIf(inst -> inst instanceof RISCVmove && ((RISCVmove) inst).getDst().equals(((RISCVmove) inst).getSrc()));
                    //将当前基本块中每条指令所使用的寄存器加入 'ifUsed' 集合
                    for (RISCVinst instr : asmBlock.getInstructionlist()) {
                        ifUsed.addAll(instr.getRegUse());
                    }
                }
            }
            for (RISCVfunction objFunction : asmModule.getFunctions()) {
                for (RISCVblock asmBlock : objFunction.getBlocks()) {
                    Iterator<RISCVinst> iterator = asmBlock.getInstructionlist().iterator();
                    while (iterator.hasNext()) {
                        RISCVinst instr = iterator.next();
                        // 检查指令的寄存器是否为空且不在 'ifUsed' 集合中
                        if (!(instr.getReg() == null) && !ifUsed.contains(instr.getReg())) {
                            // 如果寄存器是虚拟寄存器或虚拟浮点寄存器，移除该指令
                            if (instr.getReg() instanceof virtualReg || instr.getReg() instanceof virtualFReg) {
                                changed = true;
                                iterator.remove();
                            }
                        }
                    }
                }
            }
        }
    }
}
